<?php
/**     
  *
  * Copyright (c) 2009, Persistent Systems Limited
  *
  * Redistribution and use, with or without modification, are permitted 
  *  provided that the following  conditions are met:
  *   - Redistributions of source code must retain the above copyright notice, 
  *     this list of conditions and the following disclaimer.
  *   - Neither the name of Persistent Systems Limited nor the names of its contributors 
  *     may be used to endorse or promote products derived from this software 
  *     without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 
  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
  
/**
  *
  * This file contains the definition of HttpResponse Class
  */
  
/**
  * The HttpResponse Class.
  */
class HttpResponse extends Microsoft_Http_Response
{
    /**
     * @param <string> $rawHttpBatchResponse
     * @param <integer> &$index
     * @return <string> http line (ex: HTTP/1.1 202 Accepted)
     * on return $index will contains the index of http line 
     * This function will extract the final HTTP line. For example if Windows auth is
     * enabled then the http response will contains 3 http headers. First two headers
     * will be auth related and 3rd will be the actual IIS response specific to the 
     * request. We need to extract the 3rd one. Similarily in the case of Digest auth
     * the repsonse will contains one auth header and one header specific to the request
     */
    protected static function ExtractCorrectHttpLine($rawHttpResponse, &$index = 0)
    {
        if(preg_match_all ("|HTTP/[\d\.x]+ \d+ [^\r\n]+|", $rawHttpResponse, $multiArray, PREG_OFFSET_CAPTURE))
        {
            if (isset($multiArray[0]))
            {			
                if (!(isset($multiArray[0][0]) && isset($multiArray[0][0][0])))
                {
                    return null;
                }
                $correctHeaderIndex = count($multiArray[0]) - 1;
                $index = $multiArray[0][$correctHeaderIndex][1];
                return $multiArray[0][$correctHeaderIndex][0];
            }
        }
        return null;
    }
    
    /**
     * Since the http response from sever can contains multiple headers
     * (for ex: if auth is enabled on the server). The part we needed is
     * the final http header + body 
     * 
     */
    protected static function ExtractCorrectResponse($rawHttpResponse)
    {		
        $index;
        self::ExtractCorrectHttpLine($rawHttpResponse, $index);
        return  substr($rawHttpResponse, $index);
    }
    
    /**
     * Extract the response code from a response string
     *
     * @param string $responseString
     * @return int
     */
    public static function extractCode($rawResponseString)
    {
        $responseString = self::ExtractCorrectResponse($rawResponseString);
        return parent::extractCode($responseString);
    }
    
     /**
     * Extract the HTTP message from a response
     *
     * @param string $responseString
     * @return string
     */
    public static function extractMessage($rawResponseString)
    {
        $responseString = self::ExtractCorrectResponse($rawResponseString);
        return parent::extractMessage($responseString);
    }
    
    /**
     * Extract the HTTP version from a response
     *
     * @param string $responseString
     * @return string
     */
    public static function extractVersion($rawResponseString)
    {
        $responseString = self::ExtractCorrectResponse($rawResponseString);
        return parent::extractVersion($responseString);
    }
    
    /**
     * Extract the headers from a response string
     *
     * @param string $responseString
     * @return array
     */
    public static function extractHeaders($rawResponseString)
    {
        $responseString = self::ExtractCorrectResponse($rawResponseString);
        return parent::extractHeaders($responseString);
    }
    
    /**
     * Extract the body from a response string
     *
     * @param string $response_str
     * @return string
     */
    public static function extractBody($rawResponseString)
    {
        $responseString = self::ExtractCorrectResponse($rawResponseString);
        return parent::extractBody($responseString);
    }
    
    /**
     * Create a new Microsoft_Http_Response object from a string
     *
     * @param string $response_str
     * @return Microsoft_Http_Response
     */
    public static function fromString($response_str)
    {
        $code    = self::extractCode($response_str);
        $headers = self::extractHeaders($response_str);
        $body    = self::extractBody($response_str);
        $version = self::extractVersion($response_str);
        $message = self::extractMessage($response_str);

        return new Microsoft_Http_Response($code, $headers, $body, $version, $message);
    }
}
?>